/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package lineage.core;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import lineage.config.L1Config;
import lineage.core.thread.pool.L1ThreadPool;
import lineage.util.Util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 游戏服务器.
 * 
 * @version 2014年3月7日下午4:50:00
 * @author jrwz
 */
public final class L1GameServer extends Thread {
    private static final Logger LOG = LoggerFactory.getLogger(L1GameServer.class);
    /** 服务端套接字. */
    private ServerSocket serverSocket;
    /** 服务器主机名. */
    private final String hostName;
    /** 服务器端口号. */
    private final int port;

    /**
     * 静态初始化器，由JVM来保证线程安全.
     */
    private static class Holder {
        static L1GameServer instance = new L1GameServer();
    }

    /**
     * 取得该类的实例.
     */
    public static L1GameServer getInstance() {
        return Holder.instance;
    }

    private L1GameServer() {
        hostName = L1Config.GAME_SERVER_HOST_NAME;
        port = L1Config.GAME_SERVER_PORT;
        try {
            // 测试
            // InetAddress[] ips = InetAddress.getAllByName("localhost");
            // if (ips != null) {
            // for (InetAddress ip : ips) {
            // Util.message(ip.getHostAddress());
            // }
            // }
            if (!hostName.equals("*")) {
                final InetAddress inetaddress = InetAddress.getByName(hostName);
                inetaddress.getHostAddress();
                serverSocket = new ServerSocket(port, 50, inetaddress);
            } else {
                serverSocket = new ServerSocket(port);
            }
        } catch (final IOException e) {
            LOG.error(e.getLocalizedMessage(), e);
        } finally {
            Util.message(Util.SYSTEM_MESSAGE, "服务器端口：" + port);
        }
    }

    /**
     * 初始化.
     */
    public void init() {
        L1ThreadPool.getInstance().execute(this);
    }

    @Override
    public void run() {
        try {
            while (serverSocket != null) {
                Socket socket = null;
                try {
                    socket = serverSocket.accept(); // 侦听并接受到此套接字的连接(在连接之前会一直阻塞)
                    if (socket != null) {
                        final String ip = socket.getInetAddress().getHostAddress();

                        final StringBuilder sb = new StringBuilder();
                        sb.append("连线信息：\t(");
                        sb.append(ip);
                        sb.append(")\t尝试连接 ");
                        Util.message(Util.SYSTEM_MESSAGE, sb.toString());

                        L1GameClient client = new L1GameClient(socket);
                        L1ThreadPool.getInstance().execute(client);
                    }
                } catch (final SecurityException e) {
                    // TODO
                }
            }
        } catch (final IOException e) {
            LOG.error(e.getLocalizedMessage(), e);
        }
    }
}
